package com.four.seckill.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.generator.config.IFileCreate;
import com.four.seckill.dao.AttributeMapper;
import com.four.seckill.dao.SeckillInfoMapper;
import com.four.seckill.entity.Attribute;
import com.four.seckill.entity.Seckill;
import com.four.seckill.dao.SeckillMapper;
import com.four.seckill.entity.SeckillInfo;
import com.four.seckill.feign.UserFeginservice;
import com.four.seckill.service.ISeckillService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.four.seckill.vo.SeckillVo;
import com.four.seckill.vo.SeckillVo2;
import com.guli.common.utils.R;
import com.guli.common.vo.UserVo;
import io.swagger.models.auth.In;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author gs
 * @since 2021-12-22
 */
@Service
public class SeckillServiceImpl extends ServiceImpl<SeckillMapper, Seckill> implements ISeckillService {

    @Autowired
    private SeckillMapper seckillMapper;
    @Autowired
    private SeckillInfoMapper seckillInfoMapper;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private UserFeginservice userFeginservice;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private AttributeMapper attributeMapper;

    @Override
    public void addVo(SeckillVo vo) {
        Seckill seckill = new Seckill();

        /**
         *   秒杀时段
         */
        seckill.setSeKillPeriod(vo.getSeKillPeriod());
        /**
         * 商品图片
         */
        seckill.setManIocn(vo.getManIocn());
        /**
         * 活动标题
         */
        seckill.setSeTitle(vo.getSeTitle());
        /**
         * 活动简介
         */
        seckill.setSeContent(vo.getSeContent());
        /**
         * 原价
         */
        seckill.setSeOrginalPrice(vo.getSeOrginalPrice());
        /**
         * 秒杀价
         */
        seckill.setSePriceSpike(vo.getSePriceSpike());
        /**
         * 限量
         */
        seckill.setSeLimit(vo.getSeLimit());
        /**
         * 限量剩余
         */
        seckill.setSeLimitSurplus(vo.getSeLimitSurplus());
        /**
         * 秒杀状态
         */
        seckill.setSeStatus(vo.getSeStatus());
        /**
         * 状态
         */
        seckill.setStatus(vo.getStatus());
        /**
         * 创建时间
         */
        seckill.setCreateTime(new Date());
        /**
         * 秒杀配置id
         */
        seckill.setConId(vo.getConId());
        /**
         *  单位
         */
        seckill.setSeCompany(vo.getSeCompany());

        seckillMapper.addSeckill(seckill);

        Integer seId = seckill.getSeId();
        System.out.println(seId);

        Attribute attribute = new Attribute();

        /**
         * 颜色
         */
        attribute.setAttColor(vo.getAttColor());
        /**
         *内存
         */
        attribute.setAttMemory(vo.getAttMemory());
        /**
         *  秒杀价
         */
        attribute.setAttShajia(seckill.getSePriceSpike());
        /**
         * 成本价
         */
        attribute.setAttCostprice(vo.getAttCostprice());
        /**
         * 原价
         */
        attribute.setAttOriginalprice(vo.getSeOrginalPrice());
        /**
         * 库存
         */
        attribute.setAttRepertory(vo.getAttRepertory());
        /**
         * 限量
         */
        attribute.setAttLimited(vo.getAttLimited());
        /**
         * 图片
         */
        attribute.setAllImg(vo.getAllImg());
        /**
         * 重量
         */
        attribute.setAttWeight(vo.getAttWeight());
        /**
         * 体积
         */
        attribute.setAttVolume(vo.getAttVolume());
        /**
         * 商品编号
         */
        attribute.setManId(seId);

        attributeMapper.insert(attribute);
    }

    @Override
    public Seckill getByIds(Integer id) {
        return seckillMapper.getByIds(id);
    }

    @Override
    public void updateApp(Seckill seckill) {
        seckillMapper.updateById(seckill);
    }

    @Override
    public IPage<SeckillVo2> findAll(Integer page, Integer pageSize) {

        Page<SeckillVo2> vo2Page = new Page<>();


        return attributeMapper.findAll(vo2Page);
    }

    /**
     * 用户秒杀商品
     * @param seId
     * @param userName
     * @return
     */
    @Override
    public R userseckillgoods(Integer seId, String userName) {

        //根据用户名查询秒杀用户的信息
        UserVo byUname = userFeginservice.findByUname(userName);
        /**
         * 创建一个秒杀记录实体类
         */
        SeckillInfo seckillInfo = new SeckillInfo();

        RLock lock = redissonClient.getLock("fourSeckill");

        try {
            lock.lock();
            /**
             * 查询当前要秒杀的商品
             */
            Seckill seckill = seckillMapper.selectId(seId);
            //秒杀状态
            Integer seStatus = seckill.getSeStatus();
            //状态
            Integer status = seckill.getStatus();
            //商品名称
            String manName = seckill.getManName();

            //根据秒杀状态进行判断
            if (status ==0){
                return R.error(500,"该商品秒杀活动还未开启，敬请期待");
            }else{
                if(seStatus ==0){
                    return R.error(500,"该商品秒杀活动还未开启，敬请期待");
                }else if (seStatus == 2){
                    return R.error(500,"该商品秒杀活动已结束");


                }else {
                    Integer integer = (Integer) redisTemplate.opsForValue().get("seckill:serviceimpl" + seId.toString());
                    if (integer!=null){
                        if (integer>0){
                            Integer limitout = integer - 1;
                            Integer updatelimitout  = baseMapper.updates(seId,limitout);
                            if (updatelimitout>0){
                                /**
                                 * 添加秒杀记录
                                 */
                                seckillInfo.setUserName(userName);
                                seckillInfo.setSeId(seId);
                                seckillInfo.setSeName(seckill.getManName());
                                seckillInfo.setSeStatic(1);
                                seckillInfo.setSeDate(new Date());
                                seckillInfoMapper.insert(seckillInfo);
                                /**
                                 * 同步到redis
                                 */
                                redisTemplate.opsForValue().set("seckill:serviceimpl" +seId.toString(),limitout);
                                return R.ok().put("ok","当前商品"+seId+"库存为"+integer+"恭喜"+userName+"秒杀成功");

                            }else {
                                return R.ok().put("ok","库存为"+integer+"秒杀失败");
                            }

                        }else {
                            seckillInfo.setUserName(userName);
                            seckillInfo.setSeId(seId);
                            seckillInfo.setSeName(seckill.getManName());
                            seckillInfo.setSeStatic(0);
                            seckillInfo.setSeDate(new Date());
                            seckillInfoMapper.insert(seckillInfo);
                            return R.ok().put("ok", "当前商品"+seckill.getManName()+"库存为" + integer + "秒杀失败");

                        }
                    }else {
                        Integer seLimitSurplus = seckill.getSeLimitSurplus();
                        redisTemplate.opsForValue().set("seckill:serviceimpl" + seId.toString(),seLimitSurplus,300000, TimeUnit.MILLISECONDS);
                        if (seLimitSurplus>0){

                            Integer limitout = seLimitSurplus - 1;
                            Integer updatelimitout  = baseMapper.updates(seId,limitout);
                            if(updatelimitout>0){

                            seckillInfo.setUserName(userName);
                            seckillInfo.setSeId(seId);
                            seckillInfo.setSeName(seckill.getManName());
                            seckillInfo.setSeStatic(1);
                            seckillInfo.setSeDate(new Date());
                            seckillInfoMapper.insert(seckillInfo);

                            redisTemplate.opsForValue().set("seckill:serviceimpl" +seId.toString(),limitout);
                            return R.ok().put("ok","当前商品"+seId+"库存为"+integer+"恭喜"+userName+"秒杀成功");
                            }else{
                                return R.ok().put("ok","库存为"+integer+"秒杀失败");
                            }
                        }else{
                            seckillInfo.setUserName(userName);
                            seckillInfo.setSeId(seId);
                            seckillInfo.setSeName(seckill.getManName());
                            seckillInfo.setSeStatic(0);
                            seckillInfo.setSeDate(new Date());
                            seckillInfoMapper.insert(seckillInfo);
                            return R.ok().put("ok", "当前商品"+seckill.getManName()+"库存为" + integer + "秒杀失败");

                        }
                    }
                }
            }



        }catch (Exception e){
            e.printStackTrace();
        }finally{
            lock.unlock();
        }


        return R.error(405,"响应超时请重新加载");
    }


}
